#pragma once
#ifndef SM2_H
#define SM2_H
#define THIRTY_TRHREE 32  // 公钥和私钥的大小

#include "ellipse.h"
#include "sm3.h"  
#include "Crypto_Types.h"

/**
* Definition of Key in SM2
* 
* privateKey 32 byte private key
* publicKeyX 32 byte public key X coordinate
* publicKeyX 32 byte public key Y coordinate
*/

typedef struct
{
    uint32_t privateKey[8];
    uint32_t publicKeyX[8];
    uint32_t publicKeyY[8];
} Crypto_SM2Key;

typedef struct
{
    uint64_t privateKey[4];
    uint64_t publicKeyX[4];
    uint64_t publicKeyY[4];
} Crypto_SM2Key_64;

typedef struct
{
    uint8_t privateKey[32];
    uint8_t publicKeyX[32];
    uint8_t publicKeyY[32];
} Crypto_SM2Key_Data;

typedef struct
{
    sm2_point_64t C1;
    uint8_t *C2;
    uint8_t C3[32];
} Crypto_SM2Cipher_64;
/**
* Definition of Signature in SM2
*
* r 32 byte r value of the signature
* s 32 byte s value of the signature
*/
typedef struct
{
    uint8_t r[32]; /*!< 签名 r 值 */
    uint8_t s[32]; /*!< 签名 s 值 */
} Crypto_SM2Signature;

typedef struct
{
    uint64_t r[4]; /*!< 签名 r 值 */
    uint64_t s[4]; /*!< 签名 s 值 */
} Crypto_SM2Signature_64;


/**
 * Signature function
 *
 * @param key secret key
 * @param message data awaiting signature
 * @param msgLen the length of the message
 * @param ID user ID
 * @param ID_len user identification length (in bytes)
 * @param signature signature value for message
 */
FUNC(Std_ReturnType, CRY_CODE) Crypto_SM2Sign(
    const Crypto_SM2Key_Data* key,
    uint8_t* message,
    uint32_t msgLen,
    uint8_t* ID,
    uint16_t ID_len,
	Crypto_SM2Signature *signature);

/**
 * Verification function
 *
 * @param key secret key
 * @param message data awaiting signature
 * @param msgLen the length of the message
 * @param ID user ID
 * @param ID_len user identification length (in bytes)
 * @param signature signature value for message
 */
FUNC(Std_ReturnType, CRY_CODE) Crypto_SM2Verify(
    const Crypto_SM2Key_Data* key,
    uint8_t* message,
    uint32_t msgLen,
    uint8_t* ID,
    uint16_t ID_len,
    const Crypto_SM2Signature *signature);

FUNC(Std_ReturnType, CRY_CODE) Crypto_SM2Encrypt(
    const Crypto_SM2Key* key, 
    uint8_t* message, 
    size_t klen, 
    Crypto_SM2Cipher_64 *cipher);

FUNC(Std_ReturnType, CRY_CODE) Crypto_SM2Decrypt(
    const Crypto_SM2Key* key, 
    Crypto_SM2Cipher_64 cipher, 
    size_t klen, 
    uint8_t* M_temp);


void printMessage_64(const uint8_t* message, size_t mlen);
#endif /* SM2_H */

